home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 7.2 KB | 260 lines | [TEXT/CWIE] |
- /*
- File: RAVE Utilities.cp
-
- Contains: RAVE Utilities defines a number of useful functions for working with RAVE,
- including functions to find the deepest GDevice, loading textures from a PICT
- resource, and so on. Essentially, it defines a number of pieces of common code
- that were useful to many of my projects.
-
- Written by: Timothy Carroll
-
- Copyright: Copyright ©1996-1999 by Apple Computer, Inc., All Rights Reserved.
-
- You may incorporate this Apple sample source code into your program(s) without
- restriction. This Apple sample source code has been provided "AS IS" and the
- responsibility for its operation is yours. You are not permitted to redistribute
- this Apple sample source code as "Apple sample source code" after having made
- changes. If you're going to re-distribute the source, we require that you make
- it clear in the source that the code was descended from Apple sample source
- code, but that you've made changes.
-
- Change History (most recent first):
- 7/15/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1
-
-
- */
- #include <fp.h>
- #include "Rave Utilities.h"
- #include "common stuff.h"
- #include <Memory.h>
- #include <Resources.h>
-
-
-
- /*****************************************************************************
- LOOKUP TABLES
-
- I use SIN and COS in a number of places, and we don't need perfect precision,
- so we generate a set of lookup tables on 0.5 degree increments. Most of the
- 3D math routines use these lookups to generate matrices.
- *****************************************************************************/
-
- float gSinArray[721]; // [720] = [0]
- float gCosArray[721]; // [720] = [0]
-
- OSStatus InitializeLookups(void)
- {
- int loop;
-
- for (loop = 0; loop < 720; loop++)
- {
- double angle = (loop * 0.5)/57.296;
-
- gSinArray[loop] = sin (angle);
- gCosArray[loop] = cos (angle);
- }
-
- gSinArray[720] = gSinArray[0];
- gCosArray[720] = gCosArray[0];
-
- return noErr;
- }
-
-
-
- /*****************************************************************************
- RAVE ENGINE FUNCTIONS
-
- FindTextureMappingEngine walks the list of available engines and returns
- the first engine capable of Texture Mapping that will run on the device.
-
- GetListOfEngines creates a handle filled with references to all engines
- available to the application that run on the GDevice passed in the routine.
- Pass in NULL to find all engines.
- *****************************************************************************/
-
- TQAEngine *FindTextureMappingEngine (TQADevice *device)
- {
- TQAEngine *engine = NULL;
- TQAError theQAErr = kQANoErr;
- unsigned long features;
-
- engine = QADeviceGetFirstEngine (device);
-
- while (engine != NULL)
- {
- theQAErr = QAEngineGestalt (engine,
- kQAGestalt_OptionalFeatures,
- &features);
-
- if ((theQAErr == kQANoErr) && (features & kQAOptional_Texture))
- return engine;
-
- engine = QADeviceGetNextEngine (device, engine);
- }
-
- // Failed to find an engine that supports texture mapping
- return NULL;
- }
-
-
- OSStatus GetListOfEngines (GDHandle screen, Handle *list, long *number)
- {
- OSStatus theErr = noErr;
- TQAError theQAErr = kQANoErr;
-
- long loop, tempCount;
- Handle tempList;
-
- // We need a device structure to build the list of engines.
- // We only need to set it up if we were passed a GDevice.
- TQADevice device, *devicePtr = NULL;
- TQAEngine *engine;
-
- if (screen)
- {
- device.deviceType = kQADeviceGDevice;
- device.device.gDevice = screen;
- devicePtr = &device;
- }
-
- // We walk the list of engines twice. First, we count the number
- // of engines, and allocate a handle large enough to hold the
- // engine references. Second, we walk the list a second time and
- // stuff the handle.
-
- // The software engine should always be available, so I consider
- // a count of 0 to be an error.
-
- tempCount = 0;
- engine = QADeviceGetFirstEngine (devicePtr);
- while (engine != NULL)
- {
- tempCount++;
- engine = QADeviceGetNextEngine (devicePtr, engine);
- }
-
- if (tempCount == 0)
- SIGNAL_ERROR ("\pERROR: No Engines available for this GDevice")
-
- // Allocate a handle for the list.
- tempList = NewHandle (tempCount * sizeof (TQAEngine *));
- theErr = MemError();
- FAIL_OSERR (theErr, "\pError:Unable to allocate a handle for the engine list")
- FAIL_NIL(tempList, "\pError:Unable to allocate a handle for the engine list")
-
- // Walk the list again and stuff the references into the handle
- engine = QADeviceGetFirstEngine (devicePtr);
-
- for (loop = 0; loop < tempCount; loop++)
- {
- (*(TQAEngine ***)tempList)[loop] = engine;
- engine = QADeviceGetNextEngine (devicePtr, engine);
- }
-
- // Everything went successfully, fill in the list and count and return no error;
- *list = tempList;
- *number = tempCount;
-
- goto cleanup;
-
- error:
- // If an error occurred, clear the list and return the error.
- if (theErr == noErr)
- theErr = paramErr;
-
- if (tempList)
- DisposeHandle (tempList);
-
- *list = NULL;
- *number = 0;
-
- cleanup:
-
- return theErr;
- }
-
-
- TQATexture *LoadTextureFromPictResource (TQAEngine *engine, short pictID)
- {
- TQAError theQAErr = kQANoErr;
- OSStatus theErr = noErr;
-
- TQAImage image;
- TQATexture *texture= NULL;
-
- PicHandle picture = NULL;
- Rect pictRect;
- GWorldPtr pictWorld = NULL;
- PixMapHandle pictPix = NULL;
-
- CGrafPtr savePort = NULL;
- GDHandle saveDevice = NULL;
-
- // Load the texture from the resource;
-
- picture = GetPicture (pictID);
- theErr = ResError();
- FAIL_NIL (picture, "\pERROR: Failed to load the texture resource")
- FAIL_OSERR (theErr,"\pERROR: Failed to load the texture resource")
-
- // for now, we assume that the PICT is a valid size -- that is,
- // it should be a power of 2 in both dimensions.
-
- // Create a 32-bit GWorld to hold the pix map data.
- pictRect = (**picture).picFrame;
- OffsetRect (&pictRect, -pictRect.left, -pictRect.top);
-
- theErr = NewGWorld(&pictWorld, 32, &pictRect, NULL, NULL, NULL);
- FAIL_OSERR (theErr, "\pERROR:Couldn't create the texture gworld")
- FAIL_NIL (pictWorld,"\pERROR:Couldn't create the texture gworld")
-
- pictPix = GetGWorldPixMap (pictWorld);
- FAIL_NIL (pictPix, "\pERROR:Couldn't retrieve the texture PixMap")
- FAIL_FALSE (LockPixels (pictPix),"\pERROR:Couldn't lock the texture PixMap")
-
- // Draw the picture into the GWorld
- GetGWorld (&savePort, &saveDevice);
- SetGWorld (pictWorld, NULL);
- DrawPicture(picture, &pictRect);
- SetGWorld (savePort, saveDevice);
-
- // Fill in the image structure to describe our GWorld and create the texture
- image.width = pictRect.right;
- image.height = pictRect.bottom;
- image.rowBytes = (**pictPix).rowBytes & 0x3FFF;
- image.pixmap = GetPixBaseAddr (pictPix);
-
- // Create the texture and detach it so that the engine is responsible for it
- theQAErr = QATextureNew (engine,kQATexture_None ,kQAPixel_RGB32,&image, &texture);
- if (theQAErr != kQANoErr) SIGNAL_ERROR ("\pError: RAVE failed to allocate the texture")
-
- theQAErr = QATextureDetach (engine, texture);
- if (theQAErr != kQANoErr) SIGNAL_ERROR ("\pError: RAVE failed to detach the texture")
-
- // We're done -- jump to the cleanup code and return.
- goto cleanup;
-
- error:
- // We hit an error, so we need to make sure we cleanup
- // everything and return a NULL texture
- if (texture != NULL)
- QATextureDelete (engine, texture);
- texture = NULL;
-
- cleanup:
- if (picture != NULL)
- ReleaseResource ((Handle) picture);
- if (pictWorld != NULL)
- DisposeGWorld (pictWorld);
-
- return texture;
- }
-
-
-
-
-
-
-
-